#include <vector>
#include <fstream>
#include <iostream>
#include "scope.cpp"

using namespace std;

typedef scope<vector<char>, char> abc_scope;
typedef vector<char> name;

#include "helper.cpp"

abc_scope global;

int run_program (vector<char>);
vector<char> load (char *);

int main (int argv, char * argc[])
{
   char * filename;
   
   if ( argv > 1 ) { filename = argc[1]; }
   else
   {
      cout << "ERROR: No file specified.";
      return 0;
   }
   
   run_program( load(filename) );
   
   return 0;
}

vector<char> load (char * fname)
{
   FILE * file;
   char c;
   vector<char> output;

   file = fopen(fname, "r");
   
   while ( c != EOF )
   {
      c = getc(file);
      if ( c != EOF && c != ' ' && c != '\n' ) { output.push_back(c); }
   }
   
   fclose(file);
   
   return output;
}

int run_program (vector<char> input)
{
   name tempname, tempname0;
   vector<name> temppath;
   abc_scope * current(&global);
   for ( unsigned int i = 0; i < input.size(); i ++ )
   {
      switch ( input[i] )
      {
         case 'D':
            i ++;
            switch ( input[i] )
            {
               case '\"':
                  i ++;
                  while ( input[i] != '\"' )
                  {
                     tempname.push_back(input[i]);
                     i ++;
                  }
                  i ++;
                  switch ( input[i] )
                  {
                     case '\'':
                        i ++;
                        global.add_var(tempname, input[i]);
                        break;
                     default:
                        break;
                  }
               case '^':
                  temppath = get_path_data(input, i);
                  
                  i ++;
                  while ( input[i] != '^' ) { i ++; }
                  
                  for ( unsigned int i = 0; i < temppath.size(); i ++ )
                  {
                     if ( current->get_scope(temppath[i]) == NULL ) { current = current->add_scope(temppath[i]); }
                     else { current = current->get_scope(temppath[i]); }
                  }
                  
                  i ++;
                  
                  switch ( input[i] )
                  {
                     case '\"':
                        tempname.clear();
                        i ++;
                        while ( input[i] != '\"' )
                        {
                           tempname.push_back(input[i]);
                           i ++;
                        }
                        i ++;
                        switch ( input[i] )
                        {
                           case '\'':
                              i ++;
                              current->add_var(tempname, input[i]);
                           default:
                              current->add_var(tempname, 0);
                        }
                     default:
                        break;
                  }
                  break;
               default:
                  break;
            }
            break;
         case '<':
            i ++;
            switch ( input[i] )
            {
               case '\"':
                  i ++;
                  while ( input[i] != '\"' )
                  {
                     tempname.push_back(input[i]);
                     i ++;
                  }
                  cout << global.get_var(tempname) << endl;
                  break;
               case '^':
                  temppath = get_path_data(input, i);
                  i ++;
                  switch ( input[i] )
                  {
                     case '\"':
                        i ++;
                        tempname.clear();
                        while ( input[i] != '\"' )
                        {
                           tempname.push_back(input[i]);
                        }
                        cout << global.get_path_var(temppath, tempname);
                  }
               default:
                  break;
            }
         default:
            break;
      }
      tempname.clear();
      tempname0.clear();
      temppath.clear();
   }
   return 0;
}
